import random
from django import forms
from django.db.models import Q
from django.conf import settings
from django.core.validators import RegexValidator
from django.core.exceptions import ValidationError
from django.shortcuts import HttpResponse
from django_redis import get_redis_connection
from utils import Md5
from chart_web import models
from utils.tencent import sms


class tencent_sms(forms.Form):
    '''发送短信form'''
    telephone = forms.CharField(label='手机号',
                                validators=[RegexValidator(r'^1[3-9][0-9]{9}$', '手机号格式错误！')]
                                )

    def __init__(self, request, *args, **kwargs):
        super(tencent_sms, self).__init__(*args, **kwargs)
        self.request = request

    def clean_telephone(self):
        # 校验当前模板是否存在
        tpl = self.request.POST.get('tpl')  # login
        tpl_templates = settings.TENCENT_SMS_TEMPLATES.get(tpl)  # 993155
        telephone = self.cleaned_data.get('telephone')
        # print(telephone)
        if not telephone:
            raise ValidationError('手机号不能为空')
        if not tpl_templates:
            raise ValidationError('模板错误')
        # 修改手机号验证码校验
        if tpl == 'modify_telephone':
            # 进行手机号的查询，如果存在，则无法通过
            exist = models.UserInfo.objects.filter(telephone=telephone).exists()
            if exist:
                raise ValidationError('当前手机号已经存在')
        elif tpl == 'modify_password':
            # 查询是否为当前用户登录的手机号
            user_obj = models.UserInfo.objects.filter(telephone=telephone,
                                                      username=self.request.chart_web.user.username).first()
            if not user_obj:
                raise ValidationError('修改密码,需要当前用户绑定的手机号')
        # 发送验证码
        code = random.randrange(1000, 99999)
        res = sms.send_sms_single(telephone, tpl_templates, [code, ])
        # 发送成功存redis
        if res["result"] != 0:
            raise ValidationError(res['errmsg'])
        conn = get_redis_connection("default")
        conn.set(telephone, code, ex=60 * 60 * 24 * 14)
        return telephone


class register_login(forms.ModelForm):
    '''登录注册'''
    telephone = forms.CharField(label='手机号',
                                validators=[RegexValidator(r'^1[3-9][0-9]{9}$', '手机号格式错误！')])
    code = forms.CharField()

    class Meta:
        model = models.UserInfo
        fields = ['telephone', 'password', 'code']

    def __init__(self, request, *args, **kwargs):
        super(register_login, self).__init__(*args, **kwargs)
        self.request = request

    def clean_password(self):
        # 加密
        password = self.cleaned_data.get('password')
        password = Md5.md5(password)
        return password

    def clean_code(self):
        # 通过手机号获取code_redis 与code进行比较，
        telephone = self.cleaned_data.get('telephone')
        code = self.cleaned_data.get('code')
        conn = get_redis_connection("default")
        redis_code = conn.get(telephone)
        if not code:
            raise ValidationError('验证码不能为空')
        if not redis_code:
            raise ValidationError('验证码过期，请重新发送!')
        if code.strip() != redis_code.decode('utf-8'):
            raise ValidationError('验证码错误')
        return code

    def clean(self):
        # 手机号查询
        # 如果存在，登录,登录失败错误信息渲染
        # 如果不存在，不走当前校验
        telephone = self.cleaned_data.get('telephone')
        password = self.cleaned_data.get('password')
        exist = models.UserInfo.objects.filter(telephone=telephone, is_show=False).exists()
        if exist:
            # 登录校验
            user_obj = models.UserInfo.objects.filter(telephone=telephone, password=password, is_show=False).first()
            if user_obj:
                self.request.session['user_id'] = user_obj.id
            else:
                self.add_error('telephone', '手机号或者密码错误，请重新输入!')
        else:
            # 查询是否当前手机号是否注销过，注销过，无法在进行注册，联系管理员进行恢复
            cancellation_user = models.UserInfo.objects.filter(telephone=telephone, is_show=True).exists()
            if cancellation_user:
                self.add_error('telephone', '当前手机号注销过，无法在进行注册，请联系管理员进行恢复!')
        return self.cleaned_data


class modify_telephone(forms.ModelForm):
    '''修改手机号验证码form'''
    telephone = forms.CharField(label='手机号',
                                validators=[RegexValidator(r'^1[3-9][0-9]{9}$', '手机号格式错误！')]
                                )
    code = forms.CharField()

    class Meta:
        model = models.UserInfo
        fields = ['telephone', 'code']

    def clean_code(self):
        # 通过手机号获取code_redis 与code进行比较，
        telephone = self.cleaned_data.get('telephone')
        code = self.cleaned_data.get('code')
        conn = get_redis_connection("default")
        redis_code = conn.get(telephone)
        if not code:
            raise ValidationError('验证码不能为空')
        if not redis_code:
            raise ValidationError('验证码过期，请重新发送!')
        if code.strip() != redis_code.decode('utf-8'):
            raise ValidationError('验证码错误')
        return code


class modify_password(forms.ModelForm):
    '''修改密码'''
    telephone = forms.CharField(label='手机号',
                                validators=[RegexValidator(r'^1[3-9][0-9]{9}$', '手机号格式错误！')]
                                )
    code = forms.CharField()

    class Meta:
        model = models.UserInfo
        fields = ['telephone', 'password', 'code']

    def __init__(self, request, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.request = request

    def clean_password(self):
        telephone = self.cleaned_data.get('telephone')
        # 去自己的表里面查询修改的密码是否跟原密码一致，一致----返回错误。
        user_obj = models.UserInfo.objects.filter(telephone=telephone,
                                                  username=self.request.chart_web.user.username).first()
        old_password = user_obj.password
        password = Md5.md5(self.cleaned_data.get('password'))
        if not old_password:
            raise ValidationError('修改密码,需要当前绑定的手机号')
        if password == old_password:
            raise ValidationError('新旧密码不能一样')
        # 加密返回
        return password

    def clean_code(self):
        # 通过手机号获取code_redis 与code进行比较，
        telephone = self.cleaned_data.get('telephone')
        code = self.cleaned_data.get('code')
        conn = get_redis_connection("default")
        redis_code = conn.get(telephone)
        if not code:
            raise ValidationError('验证码不能为空')
        if not redis_code:
            raise ValidationError('验证码过期，请重新发送!')
        if code.strip() != redis_code.decode('utf-8'):
            raise ValidationError('验证码错误')
        return code


class modify_username(forms.ModelForm):
    '''修改用户名'''

    class Meta:
        model = models.UserInfo
        fields = ['username']

    def __init__(self, request, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.request = request

    def clean_username(self):
        # 待修改的名称与原名称进行比较
        username = self.cleaned_data.get('username')
        old_username = self.request.chart_web.user.username
        if old_username == username.strip(' '):
            raise ValidationError('新名称不能与老名称一样')
        if not username:
            raise ValidationError('用户名不能空')
        return username
